package com.sdksoft.readcard.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.util.Base64;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by hasee on 2016-08-23.
 */
public class ImgUtils {

    public static byte[] yuv2RgbByte(byte[] frame, int width, int height) {
        try {
            ByteArrayOutputStream nowImageBaos = new ByteArrayOutputStream();
            YuvImage yuvimage = new YuvImage(frame, ImageFormat.NV21, width, height, null);
            yuvimage.compressToJpeg(new Rect(0, 0, width, height), 100, nowImageBaos);
            nowImageBaos.flush();
            nowImageBaos.close();
            return nowImageBaos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] bitmap2Bytes(Bitmap bm, int quality) {
        if (bm == null)
            return null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, quality, baos);
        return baos.toByteArray();
    }

    public static void saveBitmapFile(Bitmap bitmap, File file) {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            fileOutputStream.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void saveBitmapFile(Bitmap bitmap, String path) {
        try {
            // 压缩尺寸，最大 300 * 300
            Bitmap scaledBitmap = scaledBitmap(bitmap, 300, 300);
            // 质量压缩，最大 64Kb
            Bitmap compressQuality = compressQuality(64, scaledBitmap);
            FileOutputStream fileOutputStream = new FileOutputStream(path);
            BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
            compressQuality.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            fileOutputStream.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Bitmap yuvToBitmap(byte[] frame, int width, int height) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            YuvImage yuvimage = new YuvImage(frame, ImageFormat.NV21, width, height, null);
            yuvimage.compressToJpeg(new Rect(0, 0, width, height), 100, bos);
            byte[] photo = bos.toByteArray();
            return BitmapFactory.decodeByteArray(photo, 0, photo.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getBase64ImgCompressQuality(String path, boolean isBase64Head, int maxSizeKb, int reqWidth, int reqHeight) {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            Bitmap bitmap = BitmapFactory.decodeFile(path, options);
            Bitmap scaledBitmap = ImgUtils.scaledBitmap(bitmap, reqWidth, reqHeight);
            Bitmap compressBitmap = ImgUtils.compressQuality(maxSizeKb, scaledBitmap);
            return ImgUtils.bmp2Base64String(compressBitmap, isBase64Head);
        } catch (Exception e) {
            return "";
        }
    }

    public static String getBase64ImgCompressQuality(String path, boolean isBase64Head, int maxSizeKb, int reqWidth, int reqHeight, File saveFile) {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            Bitmap bitmap = BitmapFactory.decodeFile(path, options);
            Bitmap scaledBitmap = ImgUtils.scaledBitmap(bitmap, reqWidth, reqHeight);
            Bitmap compressBitmap = ImgUtils.compressQuality(maxSizeKb, scaledBitmap);
            if (saveFile != null) {
                saveBitmapFile(compressBitmap, saveFile);
            }
            return ImgUtils.bmp2Base64String(compressBitmap, isBase64Head);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * bitmap 质量压缩，不改变尺寸
     *
     * @param maxSizeKb 压缩到的大小 kb
     * @param bitmap
     * @return
     */
    public static Bitmap compressQuality(int maxSizeKb, Bitmap bitmap) {
        try {
            int quality = 100;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] bytes;
            do {
                quality -= 10;
                baos.reset();
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                bytes = baos.toByteArray();
            } while (bytes.length / 1024 > maxSizeKb);
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        } catch (Exception e) {
        }
        return null;
    }

    public static Bitmap scaledBitmap(Bitmap bitmap, int reqWidth, int reqHeight) {
        try {
            if (bitmap.getWidth() > reqWidth || bitmap.getHeight() > reqHeight) {
                float bi = Math.min(reqWidth * 1.0f / bitmap.getWidth(), reqHeight * 1.0f / bitmap.getHeight());
                if (bi < 1) {
                    return Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * bi), (int) (bitmap.getHeight() * bi), false);
                }
            }
        } catch (Exception e) {
        }
        return bitmap;
    }

    public static String bmp2Base64String(Bitmap bmp, boolean prefix) {
        String string = "";
        try {
            if (bmp == null)
                return string;
            ByteArrayOutputStream bStream = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, bStream);
            byte[] bytes = bStream.toByteArray();
            string = Base64.encodeToString(bytes, Base64.NO_WRAP);
            if (prefix) {
                return "data:image/jpeg;base64," + string;
            }
            return string;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return string;
    }
}
